# -*- coding: utf-8 -*-

'''
@project : SmartHomeVideo
@FileName: video_analysis_main
@Author  :linych
@Time    :2021/2/22 18:30
@Desc  :
'''

import os
import sys
import time

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import pika
import threading
import json
from VideoAnalysis.VideoDecode import ffmpeg_pipe
from VideoAnalysis.Download import video_load
from Core.redis_connecter import redis_con_dict, PARAM, TASK, PICTURE, VIDEO, TASK_NAME
from Core import conf
import cv2
import base64

host = conf.get('MQ', 'url')
username = 'test'
pwd = 'test'
user_pwd = pika.PlainCredentials(username, pwd)

queue = conf.get('MQ', 'queue')

# 建立连接，服务器地址为localhost，可指定ip地址
print(host)


def video_download(url):
    s = time.time()

    out = video_load.video_download(url)

    # print('download...use: {}'.format(time.time() - s))

    return out


def video_decoder(vinput):
    s = time.time()
    '''
    video = ffmpeg_pipe.video_decoder(out=vinput)

    res_list = []
    ss = time.time()
    for i in range(len(video)):
        retval, buffer = cv2.imencode('.jpg', video[i])
        pic_str = base64.b64encode(buffer)
        pic_str = pic_str.decode()

        res_list.append(pic_str)

    # print('base64 use : {}'.format(time.time() - ss))

    # print('ffmpeg...use: {}'.format(time.time() - s))
    '''
    time.sleep(1)
    res_list = []
    return res_list


from multiprocessing import Queue, Process

VIDEO_INPUT_LIST = Queue()


def decoder_task(que):

    Decoder_Time_list = []

    while True:


        try:
            print(que.qsize())
            data = que.get()
        except Exception as e:
            print(e)
            data = None

        if data is None:
            print('wait..........................................')
            time.sleep(0.001)
            continue


        s = time.time()

        vinput, correlation_id, routing_key = data
         

        result = []
        #result = video_decoder(vinput=vinput)

        # redis记录参数
        redis_con_dict[PARAM].hmset(correlation_id, {'routing_key': routing_key, 'correlation_id': correlation_id})
        redis_con_dict[PARAM].expire(correlation_id, 5 * 60)

        # redis存图片
        for i in range(len(result)):
            tm_key = correlation_id + '_{}'.format(i)

            # redis记录抽帧图片base64
            redis_con_dict[PICTURE].set(tm_key, result[i])
            redis_con_dict[PICTURE].expire(tm_key, 5 * 60)

            # 记录映射
            redis_con_dict[VIDEO].rpush(correlation_id, tm_key)

        redis_con_dict[VIDEO].expire(correlation_id, 5 * 60)

        redis_con_dict[TASK].rpush(TASK_NAME, correlation_id)

        PID = os.getpid()
        Decoder_Time_list.append( time.time() - s)

        print('decoder  {}...avg : {}  len:{}'.format(PID, sum(Decoder_Time_list)/len(Decoder_Time_list),len(Decoder_Time_list)))


Download_time = []

# 对RPC请求队列中的请求进行处理
def on_request(ch, method, props, body):
    global VIDEO_INPUT_LIST,Download_time

    s = time.time()
    # print('consume doing.....')
    arg_dict = json.loads(body)
    url = arg_dict.get('fileurl', '')

    routing_key = props.reply_to
    correlation_id = props.correlation_id
    # print('doing ..{}'.format(correlation_id))

    # while len(VIDEO_INPUT_LIST)>200:
    #     print('waiting...{}'.format(len(VIDEO_INPUT_LIST)))
    #     time.sleep(1)
    # 调用下载i

    # while VIDEO_INPUT_LIST.qsize() > 100:
    #     print('waiting...{}'.format(VIDEO_INPUT_LIST.qsize()))
    #     time.sleep(0.1)

    try:
        vinput = video_download(url)

        data = (vinput, correlation_id, routing_key)

        VIDEO_INPUT_LIST.put(data)

    except Exception as e:
        print(e)
    ch.basic_ack(delivery_tag=method.delivery_tag)

    Download_time.append(time.time()-s)

    print('Download avg_time : {} len:{}'.format(sum(Download_time) / len(Download_time), len(Download_time)))


def video_main():
    connection = pika.BlockingConnection(pika.ConnectionParameters(
        host=host, credentials=user_pwd))

    # 建立会话
    channel = connection.channel()

    # 声明RPC请求队列
    channel.queue_declare(queue=queue)

    # 负载均衡，同一时刻发送给该服务器的请求不超过一个
    channel.basic_qos(prefetch_count=2)

    channel.basic_consume(on_message_callback=on_request, queue=queue)

    channel.start_consuming()


if __name__ == '__main__':

    import threading

    threads = []

    download_worker = 100

    for i in range(download_worker):
        t = threading.Thread(target=video_main)
        threads.append(t)
        t.start()

    # 解码
    decoder_worker = 20

    l = []

    for i in range(decoder_worker):
        t = Process(target=decoder_task, args=(VIDEO_INPUT_LIST,))
        l.append(t)
        t.start()

    for t in threads:
        t.join()

    for t in l:
        t.join()


